`include "mycpu.h"

module mycpu_core
#(
    parameter TLBNUM = 16
)    
(
    input wire        clk,
    input wire        resetn,
    // inst sram interface
    output wire inst_sram_req,
    output wire inst_sram_wr,
    output wire [1:0] inst_sram_size,
    output wire [3:0] inst_sram_wstrb,
    output wire [31:0] inst_sram_addr,
    output wire [31:0] inst_sram_wdata,
    input wire inst_sram_addr_ok,
    input wire inst_sram_data_ok,
    input wire [31:0] inst_sram_rdata,
    // data sram interface
    output wire data_sram_req,
    output wire data_sram_wr,
    output wire [1:0] data_sram_size,
    output wire [31:0] data_sram_addr,
    output wire [3:0] data_sram_wstrb,
    output wire [31:0] data_sram_wdata,
    input wire data_sram_addr_ok,
    input wire data_sram_data_ok,
    input wire [31:0] data_sram_rdata,
    // trace debug interface
    output wire [31:0] debug_wb_pc,
    output wire [ 3:0] debug_wb_rf_we,
    output wire [ 4:0] debug_wb_rf_wnum,
    output wire [31:0] debug_wb_rf_wdata,
    // mtype
    output i_mtype,
    output d_mtype
);

reg         reset;
always @(posedge clk) reset <= ~resetn;

wire         ds_allowin;
wire         es_allowin;
wire         ms_allowin;
wire         ws_allowin;
wire         fs_to_ds_valid;
wire         ds_to_es_valid;
wire         es_to_ms_valid;
wire         ms_to_ws_valid;
wire         es_valid;
wire         ms_valid;
wire         ws_valid;
wire [`FS_TO_DS_WD -1:0] fs_to_ds_bus;
wire [`DS_TO_ES_WD -1:0] ds_to_es_bus;
wire [`ES_TO_MS_WD -1:0] es_to_ms_bus;
wire [`MS_TO_WS_WD -1:0] ms_to_ws_bus;
wire [`WS_TO_RF_WD -1:0] ws_to_rf_bus;
wire [`BR_BUS_WD -1:0] br_bus;
wire [31:0] ws_pc_gen_exec;
wire exec_flush;

wire es_tlbsrch_en;
wire [3:0] es_tlbsrch_index;
wire es_tlbsrch_hit;
//invtlb
wire es_invtlb_en;
wire [31:0] es_invtlb_rj;
wire [31:0] es_invtlb_rk;
wire [4:0] es_invtlb_op;
wire [`WS_TLB_BLK_BUS_WD-1:0] ws_tlb_blk_bus;
wire out_ws_valid;
//exp19:
wire [18:0] s0_vppn;
wire s0_va_bit12;
wire s0_found;
wire [9:0] s0_asid;
wire [19:0] s0_ppn;
wire [3:0] s0_index;
wire [5:0] s0_ps;
wire [1:0] s0_plv;
wire [1:0] s0_mat;
wire s0_d;
wire s0_v;
wire [1:0] csr_crmd_plv;
wire [18:0] es_vppn;
wire es_va_bit12;
wire s1_found;
wire [3:0] s1_index;
wire [19:0] s1_ppn;
wire [5:0] s1_ps;
wire [1:0] s1_plv;
wire [1:0] s1_mat;
wire s1_d;
wire s1_v;
//crmd_da/crmd_pg
wire csr_crmd_da;
wire csr_crmd_pg;
//crmd_datf/crmd_datm
wire [1:0] csr_crmd_datf;
wire [1:0] csr_crmd_datm;
//dmw0
wire csr_dmw0_plv0;
wire csr_dmw0_plv3;
wire [1:0] csr_dmw0_mat;
wire [2:0] csr_dmw0_pseg;
wire [2:0] csr_dmw0_vseg;
//dmw1
wire csr_dmw1_plv0;
wire csr_dmw1_plv3;
wire [1:0] csr_dmw1_mat;
wire [2:0] csr_dmw1_pseg;
wire [2:0] csr_dmw1_vseg;

assign i_mtype = csr_crmd_datf[0];
assign d_mtype = csr_crmd_datm[0];

if_stage u_if_stage(
    .clk (clk),
    .reset (reset),
    .ds_allowin (ds_allowin),
    .br_bus (br_bus),
    .fs_to_ds_valid (fs_to_ds_valid),
    .fs_to_ds_bus (fs_to_ds_bus),
    .exec_flush(exec_flush),
    .fs_ex_entry(ws_pc_gen_exec),
    .inst_sram_req(inst_sram_req),
    .inst_sram_wr(inst_sram_wr),
    .inst_sram_size(inst_sram_size),
    .inst_sram_wstrb(inst_sram_wstrb),
    .inst_sram_addr(inst_sram_addr),
    .inst_sram_wdata (inst_sram_wdata),
    .inst_sram_addr_ok(inst_sram_addr_ok),
    .inst_sram_data_ok(inst_sram_data_ok),
    .inst_sram_rdata (inst_sram_rdata),
    //tlb s0
    .s0_vppn(s0_vppn),
    .s0_va_bit12(s0_va_bit12),
    .s0_found(s0_found),
    .s0_index(s0_index),
    .s0_ppn(s0_ppn),
    .s0_ps(s0_ps),
    .s0_plv(s0_plv),
    .s0_mat(s0_mat),
    .s0_d(s0_d),
    .s0_v(s0_v),
    //crmd_da crmd_pg
    .csr_crmd_plv(csr_crmd_plv),
    .csr_crmd_da(csr_crmd_da),
    .csr_crmd_pg(csr_crmd_pg),
    //dmw0
    .csr_dmw0_plv0(csr_dmw0_plv0),
    .csr_dmw0_plv3(csr_dmw0_plv3),
    .csr_dmw0_mat(csr_dmw0_mat),
    .csr_dmw0_pseg(csr_dmw0_pseg),
    .csr_dmw0_vseg(csr_dmw0_vseg),
    //dmw1
    .csr_dmw1_plv0(csr_dmw1_plv0),
    .csr_dmw1_plv3(csr_dmw1_plv3),
    .csr_dmw1_mat(csr_dmw1_mat),
    .csr_dmw1_pseg(csr_dmw1_pseg),
    .csr_dmw1_vseg(csr_dmw1_vseg)
);

id_stage u_id_stage(
    .clk (clk),
    .reset (reset),
    .es_allowin (es_allowin),
    .ds_allowin (ds_allowin),
    .fs_to_ds_valid (fs_to_ds_valid),
    .fs_to_ds_bus (fs_to_ds_bus),
    .ds_to_es_valid (ds_to_es_valid),
    .ds_to_es_bus (ds_to_es_bus),
    .br_bus (br_bus),
    .ws_to_rf_bus (ws_to_rf_bus),
    .out_ws_valid(ws_valid),
    .es_to_ms_bus(es_to_ms_bus),
    .out_es_valid(es_valid),
    .ms_to_ws_bus(ms_to_ws_bus),
    .out_ms_valid(ms_valid),
    .data_sram_data_ok(data_sram_data_ok),
    .exec_flush(exec_flush),
    .ws_tlb_blk_bus(ws_tlb_blk_bus)
);

exe_stage u_exe_stage(
    .clk (clk),
    .reset (reset),
    .ms_allowin (ms_allowin),
    .es_allowin (es_allowin),
    .ds_to_es_valid (ds_to_es_valid),
    .ds_to_es_bus (ds_to_es_bus),
    .es_to_ms_valid (es_to_ms_valid),
    .es_to_ms_bus (es_to_ms_bus),
    .data_sram_req(data_sram_req),
    .data_sram_wr(data_sram_wr),
    .data_sram_size(data_sram_size),
    .data_sram_addr (data_sram_addr),
    .data_sram_wstrb(data_sram_wstrb),
    .data_sram_wdata (data_sram_wdata),
    .data_sram_addr_ok(data_sram_addr_ok),
    .out_es_valid(es_valid),
    .exec_flush(exec_flush),
    //tlbsrch
    .es_tlbsrch_en(es_tlbsrch_en),
    .es_tlbsrch_index(es_tlbsrch_index),
    .es_tlbsrch_hit(es_tlbsrch_hit),
    //invtlb
    .es_invtlb_en(es_invtlb_en),
    .es_invtlb_rj(es_invtlb_rj),
    .es_invtlb_rk(es_invtlb_rk),
    .es_invtlb_op(es_invtlb_op),
    //tlb s1
    .es_vppn(es_vppn),
    .es_va_bit12(es_va_bit12),
    .s1_found(s1_found),
    .s1_index(s1_index),
    .s1_ppn(s1_ppn),
    .s1_ps(s1_ps),
    .s1_plv(s1_plv),
    .s1_mat(s1_mat),
    .s1_d(s1_d),
    .s1_v(s1_v),
    //crmd_da crmd_pg
    .csr_crmd_plv(csr_crmd_plv),
    .csr_crmd_da(csr_crmd_da),
    .csr_crmd_pg(csr_crmd_pg),
    //dmw0
    .csr_dmw0_plv0(csr_dmw0_plv0),
    .csr_dmw0_plv3(csr_dmw0_plv3),
    .csr_dmw0_mat(csr_dmw0_mat),
    .csr_dmw0_pseg(csr_dmw0_pseg),
    .csr_dmw0_vseg(csr_dmw0_vseg),
    //dmw1
    .csr_dmw1_plv0(csr_dmw1_plv0),
    .csr_dmw1_plv3(csr_dmw1_plv3),
    .csr_dmw1_mat(csr_dmw1_mat),
    .csr_dmw1_pseg(csr_dmw1_pseg),
    .csr_dmw1_vseg(csr_dmw1_vseg)
);

mem_stage u_mem_stage(
    .clk (clk),
    .reset (reset),
    .ws_allowin (ws_allowin),
    .ms_allowin (ms_allowin),
    .es_to_ms_valid (es_to_ms_valid),
    .es_to_ms_bus (es_to_ms_bus),
    .ms_to_ws_valid (ms_to_ws_valid),
    .ms_to_ws_bus (ms_to_ws_bus),
    .data_sram_data_ok(data_sram_data_ok),
    .data_sram_rdata (data_sram_rdata),
    .out_ms_valid(ms_valid),
    .exec_flush(exec_flush)
);

wb_stage u_WB_stage(
    .clk (clk),
    .reset (reset),
    .ws_allowin (ws_allowin),
    .ms_to_ws_valid (ms_to_ws_valid),
    .ms_to_ws_bus (ms_to_ws_bus),
    .ws_to_rf_bus (ws_to_rf_bus),
    .exec_flush(exec_flush),
    .ws_pc_gen_exec(ws_pc_gen_exec),
    .debug_wb_rf_pc (debug_wb_pc),
    .debug_wb_rf_we (debug_wb_rf_we),
    .debug_wb_rf_wnum (debug_wb_rf_wnum),
    .debug_wb_rf_wdata (debug_wb_rf_wdata),
    .out_ws_valid(ws_valid),
    //tlbsrch
    .es_tlbsrch_en(es_tlbsrch_en),
    .es_tlbsrch_index(es_tlbsrch_index),
    .es_tlbsrch_hit(es_tlbsrch_hit),
    //invtlb
    .es_invtlb_en(es_invtlb_en),
    .es_invtlb_rj(es_invtlb_rj),
    .es_invtlb_rk(es_invtlb_rk),
    .es_invtlb_op(es_invtlb_op),
    //tlb
    .ws_tlb_blk_bus(ws_tlb_blk_bus),
    //tlb s0
    .s0_vppn(s0_vppn),
    .s0_va_bit12(s0_va_bit12),
    .s0_found(s0_found),
    .s0_index(s0_index),
    .s0_ppn(s0_ppn),
    .s0_ps(s0_ps),
    .s0_plv(s0_plv),
    .s0_mat(s0_mat),
    .s0_d(s0_d),
    .s0_v(s0_v),
    //tlb s1
    .es_vppn(es_vppn),
    .es_va_bit12(es_va_bit12),
    .s1_found(s1_found),
    .s1_index(s1_index),
    .s1_ppn(s1_ppn),
    .s1_ps(s1_ps),
    .s1_plv(s1_plv),
    .s1_mat(s1_mat),
    .s1_d(s1_d),
    .s1_v(s1_v),
    //crmd_da crmd_pg crmd_plv
    .csr_crmd_da(csr_crmd_da),
    .csr_crmd_pg(csr_crmd_pg),
    .csr_crmd_plv(csr_crmd_plv),
    //dmw0
    .csr_dmw0_plv0(csr_dmw0_plv0),
    .csr_dmw0_plv3(csr_dmw0_plv3),
    .csr_dmw0_mat(csr_dmw0_mat),
    .csr_dmw0_pseg(csr_dmw0_pseg),
    .csr_dmw0_vseg(csr_dmw0_vseg),
    //dmw1
    .csr_dmw1_plv0(csr_dmw1_plv0),
    .csr_dmw1_plv3(csr_dmw1_plv3),
    .csr_dmw1_mat(csr_dmw1_mat),
    .csr_dmw1_pseg(csr_dmw1_pseg),
    .csr_dmw1_vseg(csr_dmw1_vseg),
    //crmd_datf/crmd_datm
    .csr_crmd_datf(csr_crmd_datf),
    .csr_crmd_datm(csr_crmd_datm)
);

endmodule
